﻿using System;
using System.Data.Entity;
using System.Threading.Tasks;
using System.Linq;
using EF6PowerToolDemo.Models1;

namespace EF6PowerToolDemo
{
    /// <summary>
    /// 《Entity Framework 6 Recipes》中文翻译系列 (11) -----第三章 查询之异步查询
    /// http://www.cnblogs.com/VolcanoCloud/p/4493476.html
    /// </summary>
    public static class Class1
    {
        public static void Test()
        {
            Task t = EF6AsyncDemo();


            Console.WriteLine("\nPress <enter> to continue...");
            Console.ReadLine();
        }

        private static async Task EF6AsyncDemo()
        {
            await CleanUp();

            await LoadData();

            //await RunForEachAsyncExample();
            //await RunToListAsyncExampe();
            //await RunSingleOrDefaultAsyncExampe();
        }

        private static async Task CleanUp()
        {
            using (var context = new EFRecipesEntities())
            {

                // 清除原始数据
                // 异步执行原始SQL语句
                Console.WriteLine("Cleaning Up Previous Test Data");
                Console.WriteLine("=========\n");

                await context.Database.ExecuteSqlCommandAsync("delete from chapter3.AssociateSalary");
                await context.Database.ExecuteSqlCommandAsync("delete from chapter3.Associate");
                await Task.Delay(5000);
            }
        }

        private static async Task LoadData()
        {
            using (var context = new EFRecipesEntities())
            {
                // 添加测试数据
                Console.WriteLine("Adding Test Data");
                Console.WriteLine("=========\n");

                var assoc1 = new Associate { Name = "Janis Roberts" };
                var assoc2 = new Associate { Name = "Kevin Hodges" };
                var assoc3 = new Associate { Name = "Bill Jordan" };
                var salary1 = new AssociateSalary
                {
                    Salary = 39500M,
                    SalaryDate = DateTime.Parse("8/4/09")
                };
                var salary2 = new AssociateSalary
                {
                    Salary = 41900M,
                    SalaryDate = DateTime.Parse("2/5/10")
                };
                var salary3 = new AssociateSalary
                {
                    Salary = 33500M,
                    SalaryDate = DateTime.Parse("10/08/09")
                };

                assoc1.AssociateSalaries.Add(salary1);
                assoc2.AssociateSalaries.Add(salary2);
                assoc3.AssociateSalaries.Add(salary3);
                context.Associates.Add(assoc1);
                context.Associates.Add(assoc2);
                context.Associates.Add(assoc3);

                // 异步保存
                await context.SaveChangesAsync();
                await Task.Delay(5000);
            }
        }

        private static async Task RunForEachAsyncExample()
        {
            using (var context = new EFRecipesEntities())
            {
                Console.WriteLine("Async ForEach Call");
                Console.WriteLine("=========");

                await context.Associates.Include(x => x.AssociateSalaries).ForEachAsync(x =>
                {
                    Console.WriteLine("Here are the salaries for Associate {0}:", x.Name);

                    foreach (var salary in x.AssociateSalaries)
                    {
                        Console.WriteLine("\t{0}", salary.Salary);
                    }
                });

                await Task.Delay(5000);
            }
        }

        private static async Task RunToListAsyncExampe()
        {
            using (var context = new EFRecipesEntities())
            {
                Console.WriteLine("\n\nAsync ToList Call");
                Console.WriteLine("=========");
                var associates = await context.Associates.Include(x => x.AssociateSalaries).ToListAsync();

                foreach (var associate in associates)
                {
                    Console.WriteLine("Here are the salaries for Associate {0}:", associate.Name);
                    foreach (var salaryInfo in associate.AssociateSalaries)
                    {
                        Console.WriteLine("\t{0}", salaryInfo.Salary);
                    }
                }
                await Task.Delay(5000);
            }
        }

        private static async Task RunSingleOrDefaultAsyncExampe()
        {
            using (var context = new EFRecipesEntities())
            {
                Console.WriteLine("\n\nAsync SingleOrDefault Call");
                Console.WriteLine("=========");
                var associate = await context.Associates.Include(x => x.AssociateSalaries).FirstOrDefaultAsync(y => y.Name == "Kevin Hodges");

                Console.WriteLine("Here are the salaries for Associate {0}:", associate.Name);
                foreach (var salaryInfo in associate.AssociateSalaries)
                {
                    Console.WriteLine("\t{0}", salaryInfo.Salary);
                }

                await Task.Delay(5000);
            }
        }
    }
}